CORDIC arctan function with fixed point (i`m using Q15 format)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • astri
    New Member
    • Feb 2007
    • 10

    CORDIC arctan function with fixed point (i`m using Q15 format)

    i`m doing my thesis comparing CORDIC with polynomial in counting arctan with fixed point. I`m using Q15 format now. I`m using this site CORDIC arctan as a referenced when making with floating point. The problem there`s a lot of error when i try to make it with fixed point.

    this is my program

    Code:
    #include "Unit1.h"
    #include "math.h"
    #include "fixed_math.hpp"
    #define MAXBITS 15
    static  float invGain1;
    static  float atanTable[MAXBITS];
    static  float gain1Cordic();
    
    
    void initCordic()
    {
        /* must call this first to initialise the constants.
         * of course, here i use the maths library, but the
         * values would be precomputed.
         */
        float t = 1.0f;
        int i;
        for (i = 0; i < MAXBITS; ++i)
        {
            atanTable[i] = atan(t);
            t /= 2;
        }
    
        /* set constants */
        invGain1 = 1/gain1Cordic();
    }
    
    /* CORDIC m=1, y-->0 */
    
    Q15 cordic(Q15 &x0, Q15 &y0, Q15 &z0, Q15 vecmode)
    {
    
        short t;
        Q15 x, y, z;
        int i;
    
        t = 1.0f;
        x = x0; y = y0; z = z0;
    
        for (i = 0; i < MAXBITS; ++i)
        {
    
            double x1;
    
            if (vecmode >= 0.0f && y < vecmode || vecmode<0.0f  && z >= 0.0f)
            {
                Q15 x1 = x - y>>t;
                y = y + x>>t;
                z = z - atanTable[i];
            }
            else
            {
                Q15 x1 = x + y>>t;
                y = y - x>>t;
                z = z + atanTable[i];
            }
    
             x = x1;
            t /= 2;
        }
    
        x0 = x;
        y0 = y;
        z0 = z;
    
    }
    
    
    static  float gain1Cordic()
    {
        /* compute gain by evaluating cos(0) without inv gain */
        float x, y, z;
    
        x = 1;
        y = 0;
        z = 0;
        cordic(&x, &y, &z, 1.0f);
        return x;
    }
    
    Q15 atanCordic(Q15 a)
    {
        /* domain: all a */
        Q15 x = 1.0f;
        Q15 z = 0.0f;
        cordic(&x, &a, &z, 0.0f);
        return z;
    }
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        AnsiString buf;
        float x;
        float v,c;
    
    
        initCordic();
    
        for (x=0.0;x<=1.0;x=x+0.1)
        {
    
           Q15 y = atanCordic(x);
            v = atan(x);
    
            
            Memo1->Lines->Add(buf.sprintf("%5.2f\n", x));
            Memo2->Lines->Add(buf.sprintf("%10.6f\n",Q15ToShort(v)/32768.0));
            Memo3->Lines->Add(buf.sprintf("%10.6f\n",Q15ToShort(y)/32768.0));
            
        }
    
    
    }
    anyone can help?

    if you have suggestion about making it with others rather than Q15 format, as long it is fixed point, it is very usefull to
  • sicarie
    Recognized Expert Specialist
    • Nov 2006
    • 4677

    #2
    astri-

    I'm not sure if I can help with the logic of your program (that's a little over my head!), but it's more than likely that I or someone else browsing through would be able to help you with the error messages that you are getting, if you could post those.

    sicarie

    Comment

    • RedSon
      Recognized Expert Expert
      • Jan 2007
      • 4980

      #3
      Can you give us an example of your input and output. What kind of error are you getting?

      Comment

      • astri
        New Member
        • Feb 2007
        • 10

        #4
        i`m bolding the font ONLY for error messages(ignore the warning) in my program

        Code:
        #include "Unit1.h"
        #include "math.h"
        #include "fixed_math.hpp"
        #define MAXBITS 15
        
        static  float invGain1;
        static  float atanTable[MAXBITS];
        static  float gain1Cordic();
        
        
        void initCordic()
        {
            /* must call this first to initialise the constants.
             * of course, here i use the maths library, but the
             * values would be precomputed.
             */
            float t = 1.0f;
            int i;
            for (i = 0; i < MAXBITS; ++i)
            {
                atanTable[i] = atan(t);
                t /= 2;
            }
        
            /* set constants */
            invGain1 = 1/gain1Cordic();
        }
        
        /* CORDIC m=1, y-->0 */
        
        Q15 cordic(Q15 &x0, Q15 &y0, Q15 &z0, Q15 vecmode)
        {
        
            short t;
            Q15 x, y, z;
            int i;
        
            t = 1.0f;
            x = x0; y = y0; z = z0;
        
            for (i = 0; i < MAXBITS; ++i)
            {
        
                double x1;
        
                if (vecmode >= 0.0f && y < vecmode || vecmode<0.0f  && z >= 0.0f)
                {
                    Q15 x1 = x - y>>t;
                    y = y + x>>t;
                   [B] z = z - atanTable[i];[/B]
                }
                else
                {
                    Q15 x1 = x + y>>t;
                    y = y - x>>t;
                    [B]z = z + atanTable[i];[/B]
                }
        
                 [B]x = x1;[/B]
                t /= 2;
            }
        
            x0 = x;
            y0 = y;
            z0 = z;
        
        }
        
        
        static  float gain1Cordic()
        {
            /* compute gain by evaluating cos(0) without inv gain */
            float x, y, z;
        
            x = 1;
            y = 0;
            z = 0;
            [B]cordic(&x, &y, &z, 1.0f);[/B]-->THE MAIN PROBLEM, 
            return x;                     the error messages repeated so much in this line
        }
        
        Q15 atanCordic(Q15 a)
        {
            /* domain: all a */
            Q15 x = 1.0f;
            Q15 z = 0.0f;
            cordic(&x, &a, &z, 0.0f);
            return z;
        }
        
        void __fastcall TForm1::Button1Click(TObject *Sender)
        {
            AnsiString buf;
            float x;
            float v,c;
        
        
            initCordic();
        
            for (x=0.0;x<=1.0;x=x+0.1)
            {
        
               Q15 y = atanCordic(x);
                v = atan(x);
        
                Memo1->Lines->Add(buf.sprintf("%5.2f\n", x));
                Memo2->Lines->Add(buf.sprintf("%10.6f\n",y));
                Memo3->Lines->Add(buf.sprintf("%10.6f\n",v));
        
                
            }
        
        
        }
        this is my error messages

        [CODE]
        [C++ errorー] Unit1.cpp(67): E2015 'Q15:: operator -(const Q15 &) const' and 'Q15:: operator -(const Q30 &) const' classification are ambiguous retrieval
        [C++ errorー] Unit1.cpp(73): E2015 'Q15:: operator +(const Q15 &) const' and 'Q15:: operator +(const Q30 &) const' classification are ambigous retrieval
        [C++ error ー] Unit1.cpp(76): E2015 'Q15::Q15(const short)' and 'Q15::Q15(const float)' classification are ambigous retrieval
        [C++ warning] Unit1.cpp(84): W8070 return function value
        [C++ warning] Unit1.cpp(95): W8030 'x0' parameter(cordi c(Q15 &,Q15 &,Q15 &,Q15))is used as temporarily variables
        [C++ error] Unit1.cpp(95): E2064 'Q15 &' cant initialized as 'float *'
        [C++ error] Unit1.cpp(95): E2342 'x0'parameter is define as Q15 & so it cant be change to float *
        [C++ warning] Unit1.cpp(95): W8030 'y0' parameter(cordi c(Q15 &,Q15 &,Q15 &,Q15))is used as temporarily variables
        [C++ error] Unit1.cpp(95): E2064 'Q15 &' cant initialized as 'float *'
        [C++ error] Unit1.cpp(95): E2342 'y0'b parameter is Q15 & type and cant be change to float *
        [C++ warning] Unit1.cpp(95): W8030 'z0' parameters(cord ic(Q15 &,Q15 &,Q15 &,Q15))is used as temporarily variables
        [C++ error] Unit1.cpp(95): E2064 'Q15 &' cant initialized as 'float *'
        [C++ error] Unit1.cpp(95): E2342 'z0' parameter is Q15 & type and cant be change to float *
        [C++ warning] Unit1.cpp(97): W8004 'z' subtituted value is not use
        [C++ warning] Unit1.cpp(97): W8004 'y' subtituted value is not use [C++ warning] Unit1.cpp(104): W8030 'x0' parameter(cordi c(Q15 &,Q15 &,Q15 &,Q15))is used as temporarily variables
        [C++ error] Unit1.cpp(104): E2064 'Q15 &' is 'Q15 *' cant be initialized
        [C++ error] Unit1.cpp(104): E2342 'x0' parameters is Q15 & type and cant be change to Q15 *
        [C++ warning] Unit1.cpp(104): W8030 'y0' parameters(cord ic(Q15 &,Q15 &,Q15 &,Q15))is used as temporarily variables
        [C++ error] Unit1.cpp(104): E2064 'Q15 &' is 'Q15 *' cant be initialized
        [C++ error] Unit1.cpp(104): E2342 'y0' parameters is Q15 & type and cant be change to Q15 *
        [C++ warning] Unit1.cpp(104): W8030 'z0' パラメータ(cordic(Q1 5 &,Q15 &,Q15 &,Q15))is used as temporarily variables
        [C++ warning] Unit1.cpp(104): E2064 'Q15 &' は 'Q15 *' cant be initialized
        [C++ error] Unit1.cpp(104): E2342 'z0' parameters is Q15 & type and cant be change to Q15 *



        i`m thinking the main problem in my program is because i`m trying to use fixed point (its about the data type). I dont really understand that much.



        *ps i`m using c++builder for japanese so the error message output is in japanese , i`m translating by myself to english (so if it`s sound weird please correct it or ask me)

        Comment

        • horace1
          Recognized Expert Top Contributor
          • Nov 2006
          • 1510

          #5
          the function definition of cordic() sepcifies that the formal parameters and return type are Q15
          Code:
          Q15 cordic(Q15 &x0, Q15 &y0, Q15 &z0, Q15 vecmode)
          you call it with actual parameters of type float
          Code:
          static  float gain1Cordic()
          {
              /* compute gain by evaluating cos(0) without inv gain */
              float x, y, z;
          
              x = 1;
              y = 0;
              z = 0;
              cordic(&x, &y, &z, 1.0f);-->THE MAIN PROBLEM, 
              return x;                     the error messages repeated so much in this line
          }
          where did you get the Q15 fixed point library from?

          Comment

          • astri
            New Member
            • Feb 2007
            • 10

            #6
            Originally posted by horace1
            the function definition of cordic() sepcifies that the formal parameters and return type are Q15
            Code:
            Q15 cordic(Q15 &x0, Q15 &y0, Q15 &z0, Q15 vecmode)
            you call it with actual parameters of type float
            Code:
            static  float gain1Cordic()
            {
                /* compute gain by evaluating cos(0) without inv gain */
                float x, y, z;
            
                x = 1;
                y = 0;
                z = 0;
                cordic(&x, &y, &z, 1.0f);-->THE MAIN PROBLEM, 
                return x;                     the error messages repeated so much in this line
            }
            where did you get the Q15 fixed point library from?
            my professor make it by himself the library, i included it in fixed_math.hpp

            Comment

            • RedSon
              Recognized Expert Expert
              • Jan 2007
              • 4980

              #7
              Can you post the .hpp file with your professors code in it? If it is large consider using the website mediafire.com to upload it and give us the link to it. Also, when you translate error messages, please try to translate word for word. What I mean is don't worry about changing the grammar and word order so that is makes sense in english. We can still get the meaning even though it may not look right, and that way there is less loss in translation. :)

              Comment

              • MMcCarthy
                Recognized Expert MVP
                • Aug 2006
                • 14387

                #8
                Originally posted by RedSon
                Can you post the .hpp file with your professors code in it? If it is large consider using the website mediafire.com to upload it and give us the link to it. Also, when you translate error messages, please try to translate word for word. What I mean is don't worry about changing the grammar and word order so that is makes sense in english. We can still get the meaning even though it may not look right, and that way there is less loss in translation. :)
                Sorry guys I've already told the OP they can't as the code is copyrighted.

                Comment

                • RedSon
                  Recognized Expert Expert
                  • Jan 2007
                  • 4980

                  #9
                  The professor's code is copyrighted? Or the CORDIC code?

                  Comment

                  • astri
                    New Member
                    • Feb 2007
                    • 10

                    #10
                    Originally posted by RedSon
                    The professor's code is copyrighted? Or the CORDIC code?
                    sorry my professor code is copyrighted

                    Comment

                    • RedSon
                      Recognized Expert Expert
                      • Jan 2007
                      • 4980

                      #11
                      Would your professor not give limited permission under an academic free license for us to view his/her code?

                      Comment

                      • MMcCarthy
                        Recognized Expert MVP
                        • Aug 2006
                        • 14387

                        #12
                        Originally posted by RedSon
                        Would your professor not give limited permission under an academic free license for us to view his/her code?
                        It would have to be by PM if he/she does as it cannot be publicly published on the site.

                        Mary

                        Comment

                        • astri
                          New Member
                          • Feb 2007
                          • 10

                          #13
                          finally i can solved the errors in my program , but the counting result is wrong.Take a look in my program , where is my mistakes?

                          *ps i had count arctan using CORDIC in floating point and i use the same method when counting it in fixed point only in here i use Q15 class. i`m bold-ing the font which is different from my floating point program and Italic font is what i use for the floating point.

                          Code:
                          #include <vcl.h>
                          #pragma hdrstop
                          
                          
                          #include "Unit1.h"
                          #include "math.h"
                          #include "fixed_math.hpp"
                          #define MAXBITS 15
                          //---------------------------------------------------------------------------
                          #pragma package(smart_init)
                          #pragma resource "*.dfm"
                          TForm1 *Form1;
                          //---------------------------------------------------------------------------
                          __fastcall TForm1::TForm1(TComponent* Owner)
                                  : TForm(Owner)
                          {
                          }
                          //---------------------------------------------------------------------------
                          [B]static float atanTable[MAXBITS];[/B]
                          [I]static double atanTable[MAXBITS];[/I] 
                          
                          
                          void initCordic()
                          {
                              /* must call this first to initialise the constants.
                               * of course, here i use the maths library, but the
                               * values would be precomputed.
                               */
                          
                             [B] float t = 1.0f;[/B]
                             [I]double t = 1;[/I]
                              int s;
                              for (s = 0; s < MAXBITS; ++s)
                              {
                                  atanTable[s] = atan(t);
                                  t /= 2;
                              }
                          
                          }
                          
                          
                          /* CORDIC m=1, y-->0 */
                          
                          
                          
                          [B]Q15 cordic(Q15* x0, Q15* y0, Q15* z0, Q15 vecmode)[/B]
                          [I] void cordic(double* x0, double* y0, double* z0, double vecmode)[/I]
                          {
                          
                             [B] short t;
                             Q15 x, y, z;[/B]
                             [I]double t;
                             double x, y, z;[/I]
                              
                              int s;
                          
                              t = 1.0f;
                              x = *x0; y = *y0; z = *z0;
                          
                              for (s = 0; s < MAXBITS; ++s)
                              {
                          
                                  [B]Q15 x1;[/B]
                                 [I] double x1;  [/I]      
                          
                          
                                  if (vecmode >= 0.0f && y < vecmode || vecmode<0.0f  && z >= 0.0f)
                                  {
                                      Q15 x1 = x - y>>t;
                                      y = y + x>>t;
                                      z = z - Q15(atanTable[s]);
                                  }
                                  else
                                  {
                                      Q15 x1 = x + y>>t;
                                      y = y - x>>t;
                                      z = z + Q15(atanTable[s]);
                                  }
                          
                                  x=x1;
                                  t /= 2;
                              }
                          
                              *x0 = x;
                              *y0 = y;
                              *z0 = z;
                          
                             [B] return z;  [/B]           
                          }
                          
                          
                          [B]Q15 atanCordic(Q15 a)[/B]
                          [I]double atanCordic(double a)[/I]
                          {
                              /* domain: all a */
                          [B]Q15 x = 1.0f;
                              Q15 z = 0.0f;[/B]
                              [I]double x = 1;
                              double z = 0;[/I]
                              cordic(&x, &a, &z, 0.0f);              
                              return z;
                          }
                          
                          void __fastcall TForm1::Button1Click(TObject *Sender)
                          {
                              AnsiString buf;
                              [B]float x;
                              float y;[/B]
                              [I]double v,y,r;
                              double x;[/I]
                          
                          
                              initCordic();
                          
                              for (x=0.0;x<=1.0;x=x+0.1)
                              {
                          
                                [B] Q15 v = atanCordic(x);[/B]
                                [I] v = atanCordic(x);[/I]
                                  y = atan(x);
                          
                                  Memo1->Lines->Add(buf.sprintf("%5.2f\n", x));
                                  Memo2->Lines->Add(buf.sprintf("%10.6f\n",Q15ToShort(v)/32768.0));
                                  Memo3->Lines->Add(buf.sprintf("%10.6f\n",Q15ToShort(y)/32768.0));
                          
                              }
                          
                          
                          }
                          //---------------------------------------------------------------------------

                          Comment

                          Working...